package me.exchange.com.modules.system.service.impl;

import me.exchange.com.modules.system.domain.Appt;
import me.exchange.com.modules.system.domain.User;
import me.exchange.com.modules.system.dto.ApptDto;
import me.exchange.com.modules.system.dto.ApptQueryCriteria;
import me.exchange.com.modules.system.mapper.AppMapper;
import me.exchange.com.modules.system.repository.ApptRepository;
import me.exchange.com.modules.system.repository.UserRepository;
import me.exchange.com.modules.system.service.ApptService;
import me.exchange.com.utils.*;
import org.apache.commons.collections4.map.LinkedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;


/**
 * @author zhaojing
 * @create2020/5/20
 */
@Service
@CacheConfig(cacheNames = "appt")
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true,rollbackFor = Exception.class)
public class ApptServiceImpl implements ApptService {

    @Autowired
    private AppMapper appMapper;

    @Autowired
    private ApptRepository apptRepository;

    @Autowired
    private UserRepository userRepository;

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @Override
    @Cacheable(key = "#p0")
    public ApptDto findById(Integer id) {
        Appt appt = apptRepository.findById(id).orElseGet(Appt::new);
        ValidationUtil.isNull(appt.getId(),"Appt","id",id);
        return appMapper.toDto(appt);
    }

    /**
     * 创建
     * @param resources
     * @return
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public ApptDto create(Appt resources) {
       User user =  userRepository.findByUsername(SecurityUtils.getUsername());
       resources.setCAdminId(user.getId());
       resources.setCAdminTime(new Timestamp(System.currentTimeMillis()));
       resources.setIsdel(true);
        return appMapper.toDto(apptRepository.save(resources));
    }

    /**
     * 修改
     * @param resources
     * @return
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(Appt resources) {
        User user = userRepository.findByUsername(SecurityUtils.getUsername());
        Appt appt = apptRepository.findById(resources.getId()).orElseGet(Appt::new);
        ValidationUtil.isNull(appt.getId(),"Appt","id",resources.getId());
        appt.Copy(resources);
        appt.setCAdminId(user.getId());
        appt.setCAdminTime(new Timestamp(System.currentTimeMillis()));
        appt.setIsdel(true);
        apptRepository.save(appt);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void delete(Integer id) {
        User user = userRepository.findByUsername(SecurityUtils.getUsername());
        Appt appt = apptRepository.findById(id).orElseGet(Appt::new);
        appt.setCAdminTime(new Timestamp(System.currentTimeMillis()));
        appt.setCAdminId(user.getId());
        appt.setIsdel(false);
        apptRepository.save(appt);
    }

    /**
     * 多选删除
     * @param ids
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(Set<Integer> ids) {
        User user = userRepository.findByUsername(SecurityUtils.getUsername());
        for (Integer id: ids) {
            Appt appt = apptRepository.findById(id).orElseGet(Appt::new);
            appt.setCAdminTime(new Timestamp(System.currentTimeMillis()));
            appt.setCAdminId(user.getId());
            appt.setIsdel(false);
            apptRepository.save(appt);
        }
    }

    /**
     * 导出数据
     * @param all
     * @param response
     * @throws IOException
     */
    @Override
    public void download(List<ApptDto> all, HttpServletResponse response) throws IOException {

        List<Map<String,Object>> list = new ArrayList<>();

        for (ApptDto appt : all) {
            Map<String, Object> map = new LinkedMap<>();

            map.put("姓名",appt.getUserName());
            map.put("app类型名称",appt.getAppType());
            map.put("app语言名称",appt.getAppLanguage());
            map.put("app的版本号",appt.getAppEdition());
            map.put("app的版本更新内容",appt.getAppEditionUp());
            map.put("app的上线时间",appt.getAppShelfTime());
            map.put("app是否强制性更新",appt.getAppRenew());
            map.put("app下载地址",appt.getAppDown());
            map.put("创建人",appt.getCAdminId());
            map.put("创建日期",appt.getCAdminTime());
            map.put("修改人",appt.getUAdminId());
            map.put("修改日期",appt.getUAdminTime());
            map.put("是否删除 1未删除 0删除",appt.getIsdel());
            list.add(map);
        }

        FileUtil.downloadExcel(list,response);
    }

    /**
     * 查询
     * @param criteria
     * @return
     */
    @Override
    @Cacheable
    public List<ApptDto> queryAll(ApptQueryCriteria criteria) {

        Sort sort = criteria.getSort();

        return appMapper.toDto(apptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort));
    }

    /**
     * 分页查询
     * @param criteria
     * @param pageable
     * @return
     */
    @Override
    public Map<String, Object> queryAll(ApptQueryCriteria criteria, Pageable pageable) {

        Page<Appt> pageAppt = apptRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);

        return PageUtil.toPage(pageAppt.map(appMapper::toDto));
    }

    /**
     * 修改APP类型
     * @param criteria
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void updataType(ApptQueryCriteria criteria) {

        User user = userRepository.findByUsername(SecurityUtils.getUsername());

        Appt appt = apptRepository.findById(criteria.getId()).orElseGet(Appt::new);

        ValidationUtil.isNull(appt.getId(),"Appt","id",criteria.getId());

        appt.setUAdminId(user.getId());

        appt.setUAdminTime(new Timestamp(System.currentTimeMillis()));

        appt.setId(appt.getId());

        appt.setAppType(criteria.getAppType());

        apptRepository.save(appt);

    }


}
